package com.portal.framework.dao;

import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;

import com.portal.framework.common.lang.NameValue;
import com.portal.framework.dao.annotation.PropertySearchType;
import com.portal.framework.dao.annotation.SearchProp;
import com.portal.framework.util.StringUtils;

/**
 * 组合条件的搜索表单<BR>
 * 如果HQL不为空的时候,则ISearchForm下的所有的搜索条件属性将会不起作用
 * 
 * @return
 */
public interface ISearchForm extends JsonSupport {
	/**
	 * 最大显示的记录数
	 */
	public static final int MAX_RESULT = Integer.MAX_VALUE;

	public void addPropertyCondition(String property1, String property2,
			PropertySearchType searchType);

	public List<PropertyCondition> getPropertyCondition();

	/**
	 * 设置是否需要分页
	 * 
	 * @param isNeedPage
	 */
	public void setNeedPage(boolean isNeedPage);

	/**
	 * 当前页数
	 * 
	 * @return
	 */
	public int getPage();

	/**
	 * 每页的显示数<BR>
	 * 如果设置每页显示数 小于等于零 则将会显示所有的记录
	 * 
	 * @return
	 */
	public int getPageSize();

	/**
	 * 最大的记录数(只显示多少条记录),一般用于排行榜等<BR>
	 * 如果设置最大显示数 小于等于零 则将会显示所有的记录
	 * 
	 * @return
	 */
	public int getMaxResult();

	/**
	 * 得到排序信息
	 * 
	 * @return
	 */
	public List<NameValue<SearchOrder>> getOrderBys();

	/**
	 * 添加排序条件
	 * 
	 * @param fieldName
	 *            数据库的字段名
	 * @param orderBy
	 *            排序的顺序正向还是反向 (DESC 或 ASC)
	 */
	public void addOrderBy(String fieldName, SearchOrder orderBy);

	/**
	 * 得到HQL语句,如果HQL不为空的时候,则ISearchForm下的所有的搜索条件属性将会不起作用<BR>
	 * 该语句可以包含 'SELECT *' 也可以不包含,但必需有FROM字符.
	 * 
	 * @return
	 */
	public String getHql();

	/**
	 * @param propName
	 *            字段名
	 * @param projectionType
	 *            返回值类型,可以为如果类型为group by类型,则将添加一个group by的返回值
	 * @param alias
	 *            别名(暂时没有用上)
	 */
	public void addProjectSearchType(String propName,
			ProjectionType projectionType, String alias);

	public void addProjectSearchType(ProjectionSearchType projectionSearchType);

	/**
	 * 添加select 的返回信息的数组
	 * 
	 * @return
	 */
	public List<ProjectionSearchType> getProjectionType();

	/**
	 * 是否需要分页
	 * 
	 * @return
	 */
	public boolean isNeedPage();

	/**
	 * 得到连接模式(左连接,全连接,内连接)
	 * 
	 * @return
	 */
	public JoinMode getJoinMode();

	/**
	 * 是否唯一
	 * 
	 * @return
	 */
	public boolean isDistinct();

	/**
	 * 动态添加条件
	 * 
	 * @param fieldName
	 *            对应的DTO(Pojo)的属性名
	 * @param nullValue
	 *            当是什么值时不参加条件搜索
	 * @param searchType
	 *            搜索类型
	 * @param value
	 *            进行搜索的值
	 */
	public void addCondition(String fieldName, String nullValue,
			SearchType searchType, Object value);

	/**
	 * 动态添加条件
	 * 
	 * @param fieldName
	 *            对应的DTO(Pojo)的属性名
	 * @param nullValue
	 *            当是什么值时不参加条件搜索
	 * @param searchType
	 *            搜索类型
	 * @param value
	 *            进行搜索的值
	 * @param orkey
	 * 
	 */
	public void addCondition(String fieldName, String nullValue,
			SearchType searchType, Object value, String orKey);

	/**
	 * 动态添加条件
	 * 
	 * @param fieldName
	 *            对应的DTO(Pojo)的属性名
	 * @param nullValue
	 *            当是什么值时不参加条件搜索
	 * @param searchType
	 *            搜索类型
	 * @param value
	 *            进行搜索的值
	 */
	public void addCondition(String fieldName, SearchType searchType,
			Object value);

	/**
	 * 动态添加条件
	 * 
	 * @param fieldName
	 * @param nullValue
	 * @param searchType
	 */
	public void addCondition(SearchCondition condition);

	/**
	 * 得到动态添加的条件
	 * (a or b or c)
	 * 
	 * @return
	 */
	
	public Set<SearchCondition> getConditions();
	
	public void addConditionForAnd(String fieldName, String nullValue,SearchType searchType, Object value,String orKey);
	/**
	 * 得到动态添加的条件
	 * ((a and b and c) or (a and b and c)) 
	 * 
	 * @return
	 */
	public Set<SearchCondition> getConditionsForAnd();
	

	/**
	 * 排序的枚举类
	 */
	public static enum SearchOrder {
		// 降序
		DESC,

		// 升序
		ASC;
	}

	/**
	 * 排序的枚举类
	 */
	public static enum JoinMode {
		/**
		 * 内连接
		 */
		INNER_JOIN(Criteria.INNER_JOIN),

		/**
		 * 全连接
		 */
		FULL_JOIN(Criteria.FULL_JOIN),

		/**
		 * 左连接
		 */
		LEFT_JOIN(Criteria.LEFT_JOIN);

		private final int value;

		private JoinMode(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}
	}

	public static class PropertyCondition {
		private String property1;
		private String property2;
		private PropertySearchType propertySearchType;
		private String orKey = SearchProp.DEFAULT_OR_KEY;

		public PropertyCondition() {
			super();
		}

		public String getOrKey() {
			return orKey;
		}

		public void setOrKey(String orKey) {
			this.orKey = orKey;
		}

		public PropertyCondition(String property1, String property2,
				PropertySearchType propertySearchType) {
			super();
			this.property1 = property1;
			this.property2 = property2;
			this.propertySearchType = propertySearchType;
		}

		public String getProperty1() {
			return property1;
		}

		public void setProperty1(String property1) {
			this.property1 = property1;
		}

		public String getProperty2() {
			return property2;
		}

		public void setProperty2(String property2) {
			this.property2 = property2;
		}

		public PropertySearchType getPropertySearchType() {
			return propertySearchType;
		}

		public void setPropertySearchType(PropertySearchType propertySearchType) {
			this.propertySearchType = propertySearchType;
		}
	}

	/**
	 * 搜索的条件,方便在Action中动态添加条件
	 * 
	 * @author ¬˸��
	 * @date 2008-1-9
	 */
	public static class SearchCondition {
		private String fieldName;
		private String nullValue = ""; // 默认为 ""
		private SearchType searchType;
		private Object fieldValue;
		private String orKey = SearchProp.DEFAULT_OR_KEY;

		public String getOrKey() {
			return orKey;
		}

		public void setOrKey(String orKey) {
			this.orKey = orKey;
		}

		public SearchCondition(String fieldName, SearchType searchType,
				Object fieldValue) {
			if (StringUtils.emptyTrimed(fieldName) || searchType == null) {
				throw new IllegalArgumentException(
						"fieldName,searchType不能为null");
			}

			this.fieldName = fieldName;
			this.searchType = searchType;
			this.fieldValue = fieldValue;
		}

		public SearchCondition(String fieldName, String nullValue,
				SearchType searchType, Object fieldValue) {
			this(fieldName, searchType, fieldValue);
			this.nullValue = nullValue;
		}

		public SearchCondition(String fieldName, String nullValue,
				SearchType searchType, Object fieldValue, String orKey) {
			this(fieldName, nullValue, searchType, fieldValue);
			if (orKey != null) {
				this.orKey = orKey;
			}
		}

		public String getFieldName() {
			return fieldName;
		}

		public void setFieldName(String fieldName) {
			this.fieldName = fieldName;
		}

		public String getNullValue() {
			return nullValue;
		}

		public void setNullValue(String nullValue) {
			this.nullValue = nullValue;
		}

		public SearchType getSearchType() {
			return searchType;
		}

		public void setSearchType(SearchType searchType) {
			this.searchType = searchType;
		}

		public Object getFieldValue() {
			return fieldValue;
		}

		public void setFieldValue(Object value) {
			this.fieldValue = value;
		}

	}

}